#!/usr/bin/evn python

from google.appengine.ext import db

class GlobalCounter(db.Model):
	# the maximum index of each type.
	maxScenes = db.IntegerProperty(required=True, default=1)
	maxCorrespondences = db.IntegerProperty(required=True, default=1)
	maxMeshes = db.IntegerProperty(required=True, default=1)

	# the actual number of each.
	numScenes = db.IntegerProperty(required=True, default=0)
	numCorrespondences = db.IntegerProperty(required=True, default=0)
	numMeshes = db.IntegerProperty(required=True, default=0)

class Scene(db.Model):
	# a numeric index unique among scenes.
	index = db.IntegerProperty(required=True)

	# info about the scene.
	name = db.StringProperty()
	owner = db.UserProperty()
	amosId = db.IntegerProperty()
	
	# info about the scene's image.
	url = db.StringProperty(required=True)
	width = db.IntegerProperty(required=True)
	height = db.IntegerProperty(required=True)
	firstImage = db.BlobProperty(required=True)
	is_private = db.BooleanProperty(default = False) 
	
	# info about the scene's calibration.
	calibrated = db.BooleanProperty(required=True)
	cameraLatitude = db.FloatProperty()
	cameraLongitude = db.FloatProperty()
	cameraAltitude = db.FloatProperty()
	cameraHeading = db.FloatProperty()
	cameraTilt = db.FloatProperty()
	cameraRoll = db.FloatProperty()
	
	# info about the camera's ratings.
	ratingSum = db.IntegerProperty(required=True, default=0)
	ratingCount = db.IntegerProperty(required=True, default=0)
	ratingAverage = db.FloatProperty(default=None)
	
class Calibration(db.Model):
	# a numeric index unique among calibrations.
	index = db.IntegerProperty(required=True)

	# the scene that belongs to this Calibration.
	scene = db.ReferenceProperty(Scene)
	
	# the origin of the calibration.
	originLatitude     = db.FloatProperty(required=True)
	originLongitude    = db.FloatProperty(required=True)
	originAltitude     = db.FloatProperty(required=True)
	
	# the position of the camera in ENU.
	cameraX            = db.FloatProperty(required=True)
	cameraY            = db.FloatProperty(required=True)
	cameraZ            = db.FloatProperty(required=True)
	
	# intrinsic parameters.
	focalLengthX       = db.FloatProperty(required=True)
	focalLengthY       = db.FloatProperty(required=True)
	skew               = db.FloatProperty(required=True)
	imageCenterX       = db.FloatProperty(required=True)
	imageCenterY       = db.FloatProperty(required=True)
	intrinsicDivider   = db.FloatProperty(required=True)
	
	# the full 3x4 projection matrix.
	m11                = db.FloatProperty(required=True)
	m12                = db.FloatProperty(required=True)
	m13                = db.FloatProperty(required=True)
	m14                = db.FloatProperty(required=True)
	m21                = db.FloatProperty(required=True)
	m22                = db.FloatProperty(required=True)
	m23                = db.FloatProperty(required=True)
	m24                = db.FloatProperty(required=True)
	m31                = db.FloatProperty(required=True)
	m32                = db.FloatProperty(required=True)
	m33                = db.FloatProperty(required=True)
	m34                = db.FloatProperty(required=True)
	
	# the 3x3 rotation matrix.
	r11                = db.FloatProperty(required=True)
	r12                = db.FloatProperty(required=True)
	r13                = db.FloatProperty(required=True)
	r21                = db.FloatProperty(required=True)
	r22                = db.FloatProperty(required=True)
	r23                = db.FloatProperty(required=True)
	r31                = db.FloatProperty(required=True)
	r32                = db.FloatProperty(required=True)
	r33                = db.FloatProperty(required=True)
	
	# the 3x1 translation vector.
	tx                = db.FloatProperty()
	ty                = db.FloatProperty()
	tz                = db.FloatProperty()
	
class Correspondence(db.Model):
	# a numeric index unique among correspondences.
	index = db.IntegerProperty(required=True)

	# the scene that contains this correspondence.
	scene = db.ReferenceProperty(Scene, required=True)
	
	# the owner of the correspondence.
	owner = db.UserProperty()
	
	# the geographic location.
	latitude = db.FloatProperty(required=True)
	longitude = db.FloatProperty(required=True)
	altitude = db.FloatProperty(required=True)
	
	# the image coordinates.
	u = db.IntegerProperty(required=True)
	v = db.IntegerProperty(required=True)
	
	#the number of meshes that this vertex is incident upon.
	parentMeshes = db.IntegerProperty(required=True,default=0)
	
	# the 3D coordinates in ENU space.
	x = db.FloatProperty()
	y = db.FloatProperty()
	z = db.FloatProperty()
	
	# if the camera is calibrated, this has some info about the point's
	# reprojection.
	pixelProjectionError = db.FloatProperty()
	reprojectedU = db.FloatProperty()
	reprojectedV = db.FloatProperty()
	
class Mesh(db.Model):
	# a numeric index unique among meshes.
	index = db.IntegerProperty(required=True)

	# the scene that contains this mesh.
	scene = db.ReferenceProperty(Scene)
	
	# the owner of the mesh.
	owner = db.UserProperty()
	
	# the mesh's name.
	name = db.StringProperty(required=True)
	
	# the number of points in the mesh.
	points = db.IntegerProperty(required=True)
	
	# the triangulation of these points.
	# i.e. if triangles = [0,1,2,0,2,3], then there is a triangle
	# between vertices 0,1,2, and 0,2,3.
	triangles = db.ListProperty(long, required=True)
	
	# the mapping from this mesh's vertex map to the absolute
	# correspondence ids.
	# i.e., when I say vertex 0, I really mean correspondence 124.
	# (in case we ever have to reproduce the file)
	correspondenceMapping = db.ListProperty(long, required=True)
	
	# precomputed positions, normals, uvs, and triangles for a DAE file.
	# these values are purely for displaying the mesh.
	daePositionArray = db.TextProperty(required=True)
	daeNormalArray = db.TextProperty(required=True)
	daeUVArray = db.TextProperty(required=True)
	daeTriangles = db.TextProperty(required=True)
	nPositions = db.IntegerProperty(required=True)
	nNormals = db.IntegerProperty(required=True)
	nUVs = db.IntegerProperty(required=True)
	nTriangles = db.IntegerProperty(required=True)
	
	# the latitude, longitude, and altitude of the origin in object space.
	originLatitude = db.FloatProperty(required=True)
	originLongitude = db.FloatProperty(required=True)
	originAltitude = db.FloatProperty(required=True)
	
class Rating(db.Model):
	# the scene the user is rating.
	scene = db.ReferenceProperty(Scene, required=True)
	
	# the user that rated this scene
	user = db.UserProperty(required=True)
	
	# the amount the user rated (1-5)
	rating = db.IntegerProperty(required=True)
	
class UserObservation(db.Model):
	# some stats about when the user started and stopped.
	clockIn        = db.IntegerProperty(required=False)
	clockOut       = db.IntegerProperty(required=False)
	user           = db.UserProperty(required=False)
	numberOfClicks = db.IntegerProperty(required=False)
	scene          = db.ReferenceProperty(Scene, required=False)
	numberOfCorrespondences = db.IntegerProperty(required=False)
